package org.fjsei.yewu.controller;

import graphql.GraphQLContext;
import graphql.schema.DataFetchingEnvironment;
import lombok.extern.slf4j.Slf4j;
import org.fjsei.yewu.payload.UploadFileResponse;
import org.fjsei.yewu.resolver.TusFileUploadResolver;
import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.MutationMapping;
import org.springframework.http.HttpHeaders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;

/**支持TUS上传协议的，不是普通的http文件上传。
 * 加上UploadFileResponse返回的，报错Could not resolve view with name   in servlet with name 'dispatcherServlet'
 * 就需将@Controller 改为@RestController
 **/
@Slf4j
@RestController
@CrossOrigin(exposedHeaders = { "Location", "Upload-Offset" })
@RequestMapping("/uploadTUS")
public class TusController {

    @jakarta.annotation.Resource
    private TusFileUploadResolver tusFileUploadResolver;

    //【问题】没办法和普通http服务器客户端 XHR 模式的普通通用上传客户端对接。只能对接tus协议客户。
//    @RequestMapping(value = {"/", "/**"}, method = {RequestMethod.POST, RequestMethod.PATCH, RequestMethod.HEAD, RequestMethod.DELETE, RequestMethod.GET})
//    public void uplaod(HttpServletRequest request, HttpServletResponse response) {
//        //有毛病:前端状态缓存上一次上传同一个文件的,已经上传完成再次上传的在console会报错误, 首先发起连接http://localhost:8673/uploadTUS/67d47b27-179a-46a7-9698-a9e47577313e
//        //就报错RequestMethod.HEAD: 404 Not Found 相反情况就没有报错 HEAD: 204 No Content; 前端状态缓存清理时间?
//        tusFileUploadResolver.upload(request, response);
//    }


    //【运行顺序】POST PATCH；有时出现HEAD=>POST=》PATCH, 前端可能会附带的请求=GET; 执行顺序！ 若取消还有DELETE; 第一次最前面HEAD没有；
    //PATC似乎结束？     重新开始是HEAD；http://192.168.3.245:8673/uploadTUS/9fea10e9-6cdd-49e9-bfb5-ca9e5376ce65 //Request Method:HEAD Status Code:404 Not Found
    //中断后恢复上传的: HEAD PATCH（上传结束）；文件首次被上传没有HEAD；但是POST PATCH会有。 GET是上传结束立马顺带的。
    @RequestMapping(value = {"/", "/**"}, method = {RequestMethod.HEAD})
    public void uplaod3(HttpServletRequest request, HttpServletResponse response) {
        tusFileUploadResolver.processHead(request, response);
    }

//    @ResponseBody
    @RequestMapping(value = {"/", "/**"}, method = {RequestMethod.POST})
    public void uplaod1(HttpServletRequest request, HttpServletResponse response) throws IOException {
        tusFileUploadResolver.upload(request, response);
//        return new UploadFileResponse("WQA.Dac", "http://sdff111/ert6ertrE",
//                "wordds", 4000499);
    }

    @RequestMapping(value = {"/", "/**"}, method = {RequestMethod.PATCH})
    public void uplaodPatch2(HttpServletRequest request, HttpServletResponse response){
        try {
            String minIourl = tusFileUploadResolver.uploadPatch(request, response);
        } catch (Exception ex) {
            log.error("TUS上传处理异常: {}", ex.getMessage());
            // 不要在这里设置500状态码，让uploadPatch方法自己处理
            // 但可以记录更详细的日志
        }
        // 确保跨域头部设置
        response.setHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "Location,Upload-Offset,Upload-Length,Tus2minIoUrl");
    }

    @RequestMapping(value = {"/", "/**"}, method = {RequestMethod.DELETE})
    public void uplaod4(HttpServletRequest request, HttpServletResponse response) {
        tusFileUploadResolver.uploadDel(request, response);
    }

    //TUS基础包实际不支持GET ：因为前端会发起GET请求才保留的。
    @ResponseBody
    @RequestMapping(value = {"/", "/**"}, method = {RequestMethod.GET})
    public UploadFileResponse uplaod5(HttpServletRequest request, HttpServletResponse response) {
        tusFileUploadResolver.uploadGet(request, response);
        return new UploadFileResponse("", "", "", 1);
    }


    //【以下】不是tus内容的，附带的文件管理功能

    /**删除minIO已经上传的文件； 本人？ meta中保存的 关联的key+ID要验证；
     * GraphQL接口的, 不是RESTful的：
     */
    @MutationMapping
    @Transactional
    public String ossDeleteFile(@Argument String file,@Argument String key,@Argument String value,
                                GraphQLContext ctx, DataFetchingEnvironment env
    ) {
        String res=tusFileUploadResolver.deleteMinIO(file,key,value);
        return res;     //"成功";    //'不存在'；
    }
}

//验证授权：use cookies, the Authorization header, JWTs
